
// 实现项目中用到的琐碎功能代码
// 1. 日志宏
// 2. json的序列化和反序列化
// 3. uuid的生成

#pragma once
#include <ctime>
#include <cstdio>
#include <iostream>
#include <string>
#include <memory>
#include <jsoncpp/json/json.h>
#include <sstream>
#include <chrono>
#include <random>
#include <atomic>
#include <iomanip>

namespace RPC_project
{

#define LDBG 0
#define LINF 1
#define LERR 2

#define LDEFAULT LDBG

#define LOG(level, format, ...)                                                              \
    {                                                                                        \
        if (level >= LDEFAULT)                                                               \
        {                                                                                    \
            time_t t = time(NULL);                                                           \
            struct tm *lt = localtime(&t);                                                   \
            char time_tmp[32] = {0};                                                         \
            strftime(time_tmp, 31, "%m-%d %T", lt);                                          \
            printf("[%s][%s:%d] " format "\n", time_tmp, __FILE__, __LINE__, ##__VA_ARGS__); \
        }                                                                                    \
    }

#define DLOG(format, ...) LOG(LDBG, format, ##__VA_ARGS__);
#define ILOG(format, ...) LOG(LINF, format, ##__VA_ARGS__);
#define ELOG(format, ...) LOG(LERR, format, ##__VA_ARGS__);

    class jsonTool
    {
    public:
        // 实现数据的序列化和反序列化
        static bool serialize(const Json::Value &val, std::string &body)
        {

            std::stringstream ss;
            Json::StreamWriterBuilder swb; // 先实列化工厂类对象 ，用其生产streamwriter对象

            std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
            int ret = sw->write(val, &ss);
            if (ret != 0)
            {
                ELOG("json serialize error\n");
                return false;
            }
            body = ss.str();
            return true;
            // 智能指针自动释放sw

            //  //一定要释放sw
            //  delete sw;
        }

        static bool Deserialize(const std::string &body, Json::Value &val)
        {
            Json::CharReaderBuilder CRB; // 先实列化工厂类对象
            std::unique_ptr<Json::CharReader> cr(CRB.newCharReader());

            std::string errs;
            //解析body字符串 ,将内容写到val中
            int ret = cr->parse(body.c_str(), body.c_str() + body.size(), &val, &errs);
            if (ret == false)
            {
                ELOG("json Deserialize error: %s", errs.c_str());
                return false;
            }
            return true;
        }
    };
    class UUID
    {
        public:
            static std::string uuid()
            {
                std::stringstream ss;

                // 1. 构造⼀个机器随机数对象
                std::random_device rd;
                // 2. 以机器随机数为种⼦构造伪随机数对象
                std::mt19937 generator(rd());
                // 3. 构造限定数据范围的对象
                std::uniform_int_distribution<int> distribution(0, 255);
                //高八字节// 4. ⽣成8个随机数，按照特定格式组织成为16进制数字字符的字符串
                for (int i = 0; i < 8; i++)
                {
                    if (i == 4 || i == 6)
                        ss << "-";
                    ss << std::setw(2) << std::setfill('0') << std::hex << distribution(generator);
                }
                ss << "-";

                //低八字节// 5. 定义⼀个8字节序号，逐字节组织成为16进制数字字符的字符串
                static std::atomic<size_t> seq(1); // 00 00 00 00 00 00 00 01
                size_t cur = seq.fetch_add(1);
                for (int i = 7; i >= 0; i--)
                {
                    if (i == 5)
                        ss << "-";
                    ss << std::setw(2) << std::setfill('0') << std::hex << ((cur >> (i * 8)) & 0xFF);
                }
                return ss.str();
            }

    };


    
}